import geo2
import util
import math
import cameras
import trinity
import mathUtil
import GameWorld
AVATAR_SHOULDER_HEIGHT = 1.55
CHARACTER_OFFSET_FACTOR = 0.55
OPTIMAL_SCREEN_ASPECT_RATIO = 1.7
PITCH_OFFSET_LENGTH_MODIFIER = 0.384
CLOSEST = 0.2
ZOOM_POWER_FAR = 15
ZOOM_POWER_CLOSE = 10
MAX_MOUSE_MOVE_DELTA = 0.08
CORNER_DETECTION_SPHERE = 0.3
NORMAL_COLLISION_SPHERE = 0.35
CRITICAL_COLLISION_SPHERE = 0.1
CAMERA_BUFFER_SPHERE_RADIUS = 0.2
AVATAR_MIN_DISPLAY_DISTANCE = 0.4
NORMAL_COLLISION_SMOOTHING_STEPS = 5
COLLISION_POSPOI_TRANSITION_TIME = 1.0
CRITICAL_COLLISION_SMOOTHING_STEPS = 3
POST_COLLISION_ZOOM_OUT_ACCELERATE = 1.1
ZOOM_TOGGLE_TRANSITION_SPEEDUP_FACTOR = 1.2
CRITICAL_COLLISION_POSITIONING_RADIUS = 0.11
ZOOM_TOGGLE_TRANSITION_SPEEDUP_TEMPERING = 0.9
ZOOM_IN_ADJUSTMENT_FOR_TOGGLING_COLLISIONS = 0.05

class CharacterOffsetBehaviour(cameras.CameraBehavior):
    __guid__ = 'cameras.CharacterOffsetBehaviour'

    def __init__(self, charEntID):
        cameras.CameraBehavior.__init__(self)
        self.charEntID = charEntID
        self.centerPoint = (0, 0, 0)
        self.entity = None
        self.model = None
        self.camera = None
        self.collidingRight = False
        self.originalPitchDirection = 0
        self.lastCameraMouseYawDelta = 0
        self.lastCameraMousePitchDelta = 0
        self.colliding = False
        self.originalZoom = 1.0
        self.exitingCollision = False
        self.frameTime = 0
        self.zoomAccelerate = 1.0
        self.desiredPosAndPoiTransitionSeconds = 0.0
        self.desiredPoi = None
        self.originalPoi = None
        self.desiredZoom = None
        self.preToggleZoom = None
        self.collidingAfterZoomToggle = False
        self.lastCameraZoomData = None
        self.postZoomToggleTransitionAdjustmentRequired = False



    def YawPitchToDirectionVector(self, yaw, pitch):
        if trinity.IsRightHanded():
            direction = ((math.sin(pitch) * math.cos(yaw)),
             -math.cos(pitch),
             (math.sin(pitch) * math.sin(yaw)))
        else:
            direction = ((-math.sin(pitch) * math.cos(yaw)),
             math.cos(pitch),
             (-math.sin(pitch) * math.sin(yaw)))
        return direction



    def YawPitchDistToPoint(self, yaw, pitch, dist):
        if trinity.IsRightHanded():
            position = (((dist * math.sin(pitch)) * math.cos(yaw)),
             (-dist * math.cos(pitch)),
             ((dist * math.sin(pitch)) * math.sin(yaw)))
        else:
            position = (((-dist * math.sin(pitch)) * math.cos(yaw)),
             (dist * math.cos(pitch)),
             ((-dist * math.sin(pitch)) * math.sin(yaw)))
        return position



    def CalcCorrectCameraPoi(self, yaw, pitch, zoom, overrideCollisionLogic = False):
        if not overrideCollisionLogic:
            if ((self.camera.zoomToggle == cameras.CAMERA_ZOOM_FAR) and (abs((self.camera.zoom - self.camera.desiredZoom)) < const.FLOAT_TOLERANCE)):
                self.exitingCollision = False
                if not self.colliding:
                    self.camera.zoomAccelerate = 1.0
                return self.centerPoint
            if ((self.camera.zoomToggle == cameras.CAMERA_ZOOM_FAR) and self.exitingCollision):
                self.camera.zoomAccelerate *= (cameras.POST_COLLISION_ZOOM_OUT_ACCELERATE + self.frameTime)
                return self.centerPoint
            if not self.colliding:
                self.camera.zoomAccelerate = 1.0
                self.exitingCollision = False
        elif (self.camera.zoomToggle == cameras.CAMERA_ZOOM_FAR):
            return self.centerPoint
        pitchOffsetVectorPower = ((pitch - (math.pi / 2.0)) / (self.camera.maxPitch - (math.pi / 2.0)))
        pitchOffsetVectorPower *= cameras.PITCH_OFFSET_LENGTH_MODIFIER
        if (pitchOffsetVectorPower <= 0):
            pitchOffsetVectorPower = (pitchOffsetVectorPower / 2.0)
        pitchShiftVector = self.YawPitchToDirectionVector((yaw - 0), (pitch + (math.pi / 2.0)))
        charOffsetFactor = cameras.CHARACTER_OFFSET_FACTOR
        zoomPerc = (1.0 - ((zoom - self.camera.minZoom) / (self.camera.maxZoom - self.camera.minZoom)))
        if (zoom < self.camera.minZoom):
            zoomPerc = (zoom / self.camera.minZoom)
        charOffsetFactor *= zoomPerc
        pitchOffsetVectorPower *= zoomPerc
        screenAspectRatio = (float(uicore.triapp.width) / float(uicore.triapp.height))
        if (screenAspectRatio < cameras.OPTIMAL_SCREEN_ASPECT_RATIO):
            shorten = (screenAspectRatio / cameras.OPTIMAL_SCREEN_ASPECT_RATIO)
            charOffsetFactor *= shorten
        x = self.centerPoint[0]
        z = self.centerPoint[2]
        x0 = (x + (math.cos((yaw - (math.pi / 2))) * charOffsetFactor))
        z0 = (z + (math.sin((yaw - (math.pi / 2))) * charOffsetFactor))
        shoulderOffsetPoint = (x0,
         self.centerPoint[1],
         z0)
        newPoi = geo2.Vec3Add(shoulderOffsetPoint, ((val * pitchOffsetVectorPower) for val in pitchShiftVector))
        if self.postZoomToggleTransitionAdjustmentRequired:
            diffDist = geo2.Vec3Distance(self.camera.poi, newPoi)
            if (diffDist > const.FLOAT_TOLERANCE):
                x = mathUtil.Lerp(self.camera.poi[0], newPoi[0], ((self.frameTime * cameras.ZOOM_SPEED_MODIFIER) * self.zoomAccelerate))
                y = mathUtil.Lerp(self.camera.poi[1], newPoi[1], ((self.frameTime * cameras.ZOOM_SPEED_MODIFIER) * self.zoomAccelerate))
                z = mathUtil.Lerp(self.camera.poi[2], newPoi[2], ((self.frameTime * cameras.ZOOM_SPEED_MODIFIER) * self.zoomAccelerate))
                newPoi = (x,
                 y,
                 z)
                self.zoomAccelerate *= (cameras.ZOOM_TOGGLE_TRANSITION_SPEEDUP_FACTOR + self.frameTime)
                self.zoomAccelerate = (self.zoomAccelerate ** cameras.ZOOM_TOGGLE_TRANSITION_SPEEDUP_TEMPERING)
            else:
                self.postZoomToggleTransitionAdjustmentRequired = False
            self.zoomAccelerate = 1.0
        return newPoi



    def AvoidCollision(self, now, cameraAdvancedPos):
        zoomPower = cameras.ZOOM_POWER_CLOSE
        if (self.camera.zoomToggle == cameras.CAMERA_ZOOM_FAR):
            zoomPower = cameras.ZOOM_POWER_FAR
        properZoom = self.camera.maxZoom
        if (self.camera.zoomToggle == cameras.CAMERA_ZOOM_CLOSE):
            properZoom = self.camera.minZoom
        cornerHit = self.gameWorld.SweptSphere(self.centerPoint, cameraAdvancedPos, cameras.CORNER_DETECTION_SPHERE)
        if (cornerHit and (geo2.Vec3Distance(cornerHit[0], self.centerPoint) == 0)):
            cornerHit = None
        if (cornerHit or self.gameWorld.SphereTest(cameraAdvancedPos, cameras.NORMAL_COLLISION_SPHERE)):
            if not self.colliding:
                if (self.lastCameraMouseYawDelta > 0):
                    self.collidingRight = True
                else:
                    self.collidingRight = False
                self.originalPitchDirection = (self.lastCameraMousePitchDelta / abs(self.lastCameraMousePitchDelta))
                self.camera.yawSpeed = 0
                self.camera.pitchSpeed = 0
                self.colliding = True
                self.originalZoom = properZoom
        criticalFailInfo = self.gameWorld.SweptSphere(self.centerPoint, cameraAdvancedPos, cameras.CRITICAL_COLLISION_SPHERE)
        if criticalFailInfo:
            if (abs(self.lastCameraMouseYawDelta) > abs(self.lastCameraMousePitchDelta)):
                if self.collidingRight:
                    toZoom = (self.camera.collisionZoom - (self.lastCameraMouseYawDelta * zoomPower))
                else:
                    toZoom = (self.camera.collisionZoom + (self.lastCameraMouseYawDelta * zoomPower))
            else:
                currSign = (self.lastCameraMousePitchDelta / abs(self.lastCameraMousePitchDelta))
                if (currSign != self.originalPitchDirection):
                    toZoom = (self.camera.collisionZoom + (abs(self.lastCameraMousePitchDelta) * zoomPower))
                else:
                    toZoom = (self.camera.collisionZoom - (abs(self.lastCameraMousePitchDelta) * zoomPower))
            desiredPos = geo2.Vec3Add(criticalFailInfo[0], ((val * cameras.CRITICAL_COLLISION_POSITIONING_RADIUS) for val in criticalFailInfo[1]))
            (yaw, pitch, dist,) = self.camera.PointToYawPitchDist(desiredPos)
            self.camera.zoom = self.camera.desiredZoom = self.camera.collisionZoom = dist
            self.camera.poi = self.CalcCorrectCameraPoi(self.camera.yaw, self.camera.pitch, dist)
        if self.colliding:
            cameraAdvancedPos = self.camera.YawPitchDistToPoint(self.camera.yaw, self.camera.pitch, self.originalZoom)
            advancedPoi = self.CalcCorrectCameraPoi(self.camera.yaw, self.camera.pitch, self.originalZoom)
            cameraAdvancedPos = geo2.Vec3Add(cameraAdvancedPos, advancedPoi)
            criticalFailInfo = self.gameWorld.SweptSphere(self.centerPoint, cameraAdvancedPos, cameras.CAMERA_BUFFER_SPHERE_RADIUS)
            if ((not criticalFailInfo) and ((cornerHit is None) and (not self.gameWorld.SphereTest(cameraAdvancedPos, cameras.NORMAL_COLLISION_SPHERE)))):
                self.camera.desiredZoom = self.originalZoom
                self.camera.collisionZoom = self.camera.zoom
                self.colliding = False
                self.exitingCollision = True
            else:
                if ((abs(self.camera.mouseYawDelta) > 0) or (abs(self.camera.mousePitchDelta) > 0)):
                    if (abs(self.camera.mouseYawDelta) > abs(self.camera.mousePitchDelta)):
                        delta = self.GetCameraMouseYawDelta()
                        if self.collidingRight:
                            toZoom = (self.camera.collisionZoom - (delta * zoomPower))
                        else:
                            toZoom = (self.camera.collisionZoom + (delta * zoomPower))
                    else:
                        delta = abs(self.camera.mousePitchDelta)
                        currSign = (self.camera.mousePitchDelta / abs(self.camera.mousePitchDelta))
                        if (currSign != self.originalPitchDirection):
                            toZoom = (self.camera.collisionZoom + (delta * zoomPower))
                        else:
                            toZoom = (self.camera.collisionZoom - (delta * zoomPower))
                    zoomPos = self.camera.YawPitchDistToPoint(self.camera.yaw, self.camera.pitch, toZoom)
                    zoomPoi = self.CalcCorrectCameraPoi(self.camera.yaw, self.camera.pitch, toZoom)
                    zoomPos = geo2.Vec3Add(zoomPos, zoomPoi)
                    if ((not self.gameWorld.SphereTest(zoomPos, cameras.CRITICAL_COLLISION_SPHERE)) and self.gameWorld.SweptSphere(self.centerPoint, zoomPos, cameras.NORMAL_COLLISION_SPHERE)):
                        if ((toZoom > cameras.CLOSEST) and (toZoom < properZoom)):
                            amountPerFrame = (abs((self.camera.collisionZoom - self.camera.zoom)) / cameras.NORMAL_COLLISION_SMOOTHING_STEPS)
                            self.camera.SetCollisionZoom(toZoom, amountPerFrame)
                    if (self.camera.collisionZoom < cameras.CLOSEST):
                        amountPerFrame = (abs((self.camera.collisionZoom - self.camera.zoom)) / cameras.NORMAL_COLLISION_SMOOTHING_STEPS)
                        self.camera.SetCollisionZoom(cameras.CLOSEST, amountPerFrame)
                    if (self.camera.collisionZoom > properZoom):
                        amountPerFrame = (abs((self.camera.collisionZoom - self.camera.zoom)) / cameras.NORMAL_COLLISION_SMOOTHING_STEPS)
                        self.camera.SetCollisionZoom(properZoom, amountPerFrame)



    def GetCameraMouseYawDelta(self):
        delta = self.camera.mouseYawDelta
        if (delta < 0):
            delta = max(delta, -cameras.MAX_MOUSE_MOVE_DELTA)
        elif (delta > 0):
            delta = min(delta, cameras.MAX_MOUSE_MOVE_DELTA)
        return delta



    def LerpToDesiredPosAndPoi(self):
        x = mathUtil.Lerp(self.camera.poi[0], self.desiredPoi[0], ((self.frameTime * cameras.ZOOM_SPEED_MODIFIER) * self.zoomAccelerate))
        y = mathUtil.Lerp(self.camera.poi[1], self.desiredPoi[1], ((self.frameTime * cameras.ZOOM_SPEED_MODIFIER) * self.zoomAccelerate))
        z = mathUtil.Lerp(self.camera.poi[2], self.desiredPoi[2], ((self.frameTime * cameras.ZOOM_SPEED_MODIFIER) * self.zoomAccelerate))
        newPoi = (x,
         y,
         z)
        self.camera.zoom = mathUtil.Lerp(self.camera.zoom, self.desiredZoom, ((self.frameTime * cameras.ZOOM_SPEED_MODIFIER) * self.zoomAccelerate))
        self.zoomAccelerate *= (cameras.ZOOM_TOGGLE_TRANSITION_SPEEDUP_FACTOR + self.frameTime)
        self.zoomAccelerate = (self.zoomAccelerate ** cameras.ZOOM_TOGGLE_TRANSITION_SPEEDUP_TEMPERING)
        poiDist = geo2.Vec3Distance(self.camera.poi, self.desiredPoi)
        if ((abs((self.camera.zoom - self.desiredZoom)) < const.FLOAT_TOLERANCE) and (poiDist < const.FLOAT_TOLERANCE)):
            if (self.camera.zoomToggle == cameras.CAMERA_ZOOM_FAR):
                self.camera.zoomToggle = cameras.CAMERA_ZOOM_CLOSE
            else:
                self.camera.zoomToggle = cameras.CAMERA_ZOOM_FAR
            self.zoomAccelerate = 1.0
            if (self.camera.zoomToggle == cameras.CAMERA_ZOOM_CLOSE):
                currProperPoi = self.CalcCorrectCameraPoi(self.camera.yaw, self.camera.pitch, self.camera.zoom, overrideCollisionLogic=True)
                distToProperPoi = geo2.Vec3Distance(currProperPoi, self.desiredPoi)
                if (distToProperPoi > const.FLOAT_TOLERANCE):
                    self.postZoomToggleTransitionAdjustmentRequired = True
                    self.zoomAccelerate = 1.1
            self.camera.zoom = self.camera.desiredZoom = self.camera.collisionZoom = self.desiredZoom
            self.camera.SetPointOfInterest(self.desiredPoi)
            self.desiredPoi = None
            self.colliding = self.collidingAfterZoomToggle
            self.exitingCollision = False
            return 
        self.camera.SetPointOfInterest(newPoi)
        self.camera.desiredZoom = self.camera.collisionZoom = self.camera.zoom



    def CheckCameraCanToggleZoom(self):
        if (self.lastCameraZoomData is not None):
            useLastZoomData = True
        else:
            useLastZoomData = False
        if (self.camera.zoomToggle == cameras.CAMERA_ZOOM_CLOSE):
            toggleZoom = self.camera.maxZoom
            toggleZoomFlag = cameras.CAMERA_ZOOM_FAR
        else:
            toggleZoom = self.camera.minZoom
            toggleZoomFlag = cameras.CAMERA_ZOOM_CLOSE
        cameraCurrPos = self.camera.YawPitchDistToPoint(self.camera.yaw, self.camera.pitch, self.camera.zoom)
        currPoi = self.CalcCorrectCameraPoi(self.camera.yaw, self.camera.pitch, self.camera.zoom, overrideCollisionLogic=True)
        cameraCurrPos = geo2.Vec3Add(cameraCurrPos, currPoi)
        togglePos = self.camera.YawPitchDistToPoint(self.camera.yaw, self.camera.pitch, toggleZoom)
        currZoomToggle = self.camera.zoomToggle
        self.camera.zoomToggle = toggleZoomFlag
        togglePoi = self.CalcCorrectCameraPoi(self.camera.yaw, self.camera.pitch, toggleZoom, overrideCollisionLogic=True)
        self.camera.zoomToggle = currZoomToggle
        togglePos = geo2.Vec3Add(togglePos, togglePoi)
        moveNormal = geo2.Vec3Normalize(geo2.Vec3Subtract(togglePos, cameraCurrPos))
        add = 0
        hitDuringTransition = None
        while (add < toggleZoom):
            if ((add + NORMAL_COLLISION_SPHERE) > toggleZoom):
                add = toggleZoom
            pos = geo2.Vec3Add(cameraCurrPos, ((val * add) for val in moveNormal))
            hitDuringTransition = self.gameWorld.SphereTest(pos, NORMAL_COLLISION_SPHERE)
            add += NORMAL_COLLISION_SPHERE
            if hitDuringTransition:
                break

        hitAtDestination = self.gameWorld.SweptSphere(togglePos, cameraCurrPos, NORMAL_COLLISION_SPHERE)
        hitting = ((hitAtDestination is not None) or hitDuringTransition)
        if ((not hitting) and (not self.colliding)):
            self.camera.desiredZoom = toggleZoom
            self.camera.zoomToggle = toggleZoomFlag
        elif ((not hitting) and self.colliding):
            if useLastZoomData:
                self.desiredPoi = self.lastCameraZoomData.poi
                self.desiredZoom = self.lastCameraZoomData.zoom
            else:
                self.desiredPoi = togglePoi
                self.desiredZoom = toggleZoom
            self.preToggleZoom = self.camera.zoom
            self.originalPoi = self.camera.poi
            self.desiredPosAndPoiTransitionSeconds = 0.0
            self.collidingAfterZoomToggle = False
            self.zoomAccelerate = 1.1
        else:
            hit = self.gameWorld.SweptSphere(cameraCurrPos, togglePos, NORMAL_COLLISION_SPHERE)
            if (hit and (hit[0] == cameraCurrPos)):
                hit = self.gameWorld.LineTest(cameraCurrPos, togglePos)
                if hit:
                    hit = (hit[1], hit[2])
                else:
                    hit = self.gameWorld.LineTest(togglePoi, togglePos)
                    if hit:
                        hit = (hit[1], hit[2])
            if ((hit is not None) and (hit[0] != cameraCurrPos)):
                currZoomToggle = self.camera.zoomToggle
                desiredZoomToggle = cameras.CAMERA_ZOOM_FAR
                if (currZoomToggle == cameras.CAMERA_ZOOM_FAR):
                    desiredZoomToggle = cameras.CAMERA_ZOOM_CLOSE
                self.camera.zoomToggle = desiredZoomToggle
                normal = geo2.Vec3Normalize(geo2.Vec3Subtract(hit[0], togglePoi))
                togglePoi = self.CalcCorrectCameraPoi(self.camera.yaw, self.camera.pitch, geo2.Vec3Distance(hit[0], self.centerPoint), overrideCollisionLogic=True)
                hitPos = geo2.Vec3Add(hit[0], ((val * NORMAL_COLLISION_SPHERE) for val in hit[1]))
                desiredZoom = (toggleZoom - geo2.Vec3Distance(togglePos, hitPos))
                desiredPoi = self.CalcCorrectCameraPoi(self.camera.yaw, self.camera.pitch, desiredZoom, overrideCollisionLogic=True)
                postAdjustmentCameraPos = self.camera.YawPitchDistToPoint(self.camera.yaw, self.camera.pitch, desiredZoom)
                postAdjustmentCameraPos = geo2.Vec3Add(postAdjustmentCameraPos, desiredPoi)
                while (self.gameWorld.SphereTest(postAdjustmentCameraPos, cameras.NORMAL_COLLISION_SPHERE) and (desiredZoom > cameras.CLOSEST)):
                    desiredZoom -= cameras.ZOOM_IN_ADJUSTMENT_FOR_TOGGLING_COLLISIONS
                    if (desiredZoom < cameras.CLOSEST):
                        desiredZoom = cameras.CLOSEST
                    desiredPoi = self.CalcCorrectCameraPoi(self.camera.yaw, self.camera.pitch, desiredZoom, overrideCollisionLogic=True)
                    postAdjustmentCameraPos = self.camera.YawPitchDistToPoint(self.camera.yaw, self.camera.pitch, desiredZoom)
                    postAdjustmentCameraPos = geo2.Vec3Add(postAdjustmentCameraPos, desiredPoi)

                if useLastZoomData:
                    self.desiredPoi = self.lastCameraZoomData.poi
                    self.desiredZoom = self.lastCameraZoomData.zoom
                else:
                    self.desiredPoi = desiredPoi
                    self.desiredZoom = desiredZoom
                self.camera.zoomToggle = currZoomToggle
                self.originalPoi = self.camera.poi
                self.preToggleZoom = self.camera.zoom
                self.originalZoom = toggleZoom
                self.desiredPosAndPoiTransitionSeconds = 0.0
                self.collidingAfterZoomToggle = True
                self.zoomAccelerate = 1.1
            elif useLastZoomData:
                self.desiredPoi = self.lastCameraZoomData.poi
                self.desiredZoom = self.lastCameraZoomData.zoom
            else:
                self.desiredPoi = togglePoi
                self.desiredZoom = toggleZoom
            self.originalPoi = self.camera.poi
            self.preToggleZoom = self.camera.zoom
            self.desiredPosAndPoiTransitionSeconds = 0.0
            self.collidingAfterZoomToggle = False
            self.zoomAccelerate = 1.1
        self.camera.wantToToggleZoom = False
        self.lastCameraZoomData = None



    def ProcessCameraUpdate(self, camera, now, frameTime):
        self.camera = camera
        self.frameTime = frameTime
        if (self.entity is None):
            self.entity = self._GetEntity(self.charEntID)
            if (self.entity is None):
                raise RuntimeError("Problem retrieving the avatar's entity. cameras.CameraBehavior._GetEntity returned None for entityID", self.charEntID)
        if (self.model is None):
            self.model = self._GetEntityModel(self.charEntID)
            if (self.model is None):
                raise RuntimeError("Problem retrieving the avatar's model object. entityClient.FindEntityByID returned None for entityID", self.charEntID)
        self.centerPoint = (self.entity.position.position[0],
         (self.entity.position.position[1] + cameras.AVATAR_SHOULDER_HEIGHT),
         self.entity.position.position[2])
        cameraAdvancedPos = self.camera.YawPitchDistToPoint(self.camera.yaw, self.camera.pitch, self.camera.zoom)
        advancedPoi = self.CalcCorrectCameraPoi(self.camera.yaw, self.camera.pitch, self.camera.zoom)
        cameraAdvancedPos = geo2.Vec3Add(cameraAdvancedPos, advancedPoi)
        avatarPosRelativeToCamera = (self.centerPoint[0],
         cameraAdvancedPos[1],
         self.centerPoint[2])
        if (geo2.Vec3Distance(avatarPosRelativeToCamera, cameraAdvancedPos) < cameras.AVATAR_MIN_DISPLAY_DISTANCE):
            self.model.display = False
        else:
            self.model.display = True
        if (abs(self.camera.mouseYawDelta) != 0):
            self.lastCameraMouseYawDelta = self.GetCameraMouseYawDelta()
            self.lastCameraZoomData = None
        if (abs(self.camera.mousePitchDelta) != 0):
            self.lastCameraMousePitchDelta = self.camera.mousePitchDelta
            self.lastCameraZoomData = None
        lerpingToAPosition = (self.desiredPoi is not None)
        if (camera.wantToToggleZoom and ((not self.exitingCollision) and (not lerpingToAPosition))):
            self.CheckCameraCanToggleZoom()
            self.lastCameraZoomData = util.KeyVal(poi=self.camera.poi, zoom=self.camera.zoom)
        elif camera.wantToToggleZoom:
            self.camera.wantToToggleZoom = False
        if (self.desiredPoi is None):
            newPoi = self.CalcCorrectCameraPoi(self.camera.GetYaw(), self.camera.GetPitch(), self.camera.zoom)
            self.camera.SetPointOfInterest(newPoi)
            if (self.gameWorld is not None):
                self.AvoidCollision(now, cameraAdvancedPos)
            else:
                self._LoadGameWorld()
        else:
            self.LerpToDesiredPosAndPoi()
            self.desiredPosAndPoiTransitionSeconds += self.frameTime



exports = util.AutoExports('cameras', locals())

